﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Text.Json;

namespace Utils
{
	
	public static class Ex
	{
		/// <summary>
		/// JsonSerializer序列化JSON
		/// </summary>
		/// <param name="obj">需要转换的数据</param>
		/// <returns>序列化的字符串</returns>
		public static string ToJson(this object obj)
		{
			if (obj is string)
			{
				return obj.ToString();
			}
			return System.Text.Json.JsonSerializer.Serialize(obj, new System.Text.Json.JsonSerializerOptions
			{
				Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
				PropertyNameCaseInsensitive = true,
			});
		}
		/// <summary>
		/// JSON反序列化结构
		/// </summary>
		/// <param name="json">需要反序列化的JSON</param>
		/// <returns>反序列化结构数据</returns>
		public static JsonElement ToJsonElement(this string json)
		{			
			return System.Text.Json.JsonSerializer.Deserialize<JsonElement>(json, new System.Text.Json.JsonSerializerOptions {
				Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
				PropertyNameCaseInsensitive = true,
			});
		}
		/// <summary>
		/// JSON反序列化
		/// </summary>
		/// <typeparam name="T">对象类型</typeparam>
		/// <param name="json">需要序列化的字符串</param>
		/// <returns></returns>
		public static T ToObject<T>(this string json)
		{
			return JsonSerializer.Deserialize<T>(json, new JsonSerializerOptions {
				Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
				PropertyNameCaseInsensitive = true,
			});
		}
		/// <summary>
		/// 二进制的反序列化
		/// </summary>
		/// <typeparam name="T">对象类型</typeparam>
		/// <param name="obj">需要转换的数据</param>
		/// <returns>反序列化对象</returns>
		public static T SPClone<T>(this T obj)
		{
			BinarySerializer serializer = new BinarySerializer();
			byte[]  buffer = serializer.Serialize(obj);
			return (T)serializer.Deserialize(buffer);
		}
		/// <summary>
		/// JsonConvert 反序列化
		/// </summary>
		/// <typeparam name="T">对象类型</typeparam>
		/// <param name="json">需要转换的JSON字符串</param>
		/// <returns>反序列化对象数据</returns>
		public static T ToObject2<T>(this string json)
		{
			return Newtonsoft.Json.JsonConvert.DeserializeObject<T>(json);
		}
		/// <summary>
		///  JsonConvert的反序列化
		/// </summary>
		/// <typeparam name="T">对象类型</typeparam>
		/// <param name="me">需要换成的数据</param>
		/// <returns>反序列化数据</returns>
		public static T ToOther<T>(this object me)
		{
			if (me is string)
			{
				return me.ToString().ToObject2<T>();
			}
			string json = me.ToJson();
			return json.ToObject2<T>();
		}
    }
}

namespace System.Collections.Generic
{
	public static class Ex2
	{
		public static IEnumerable<TSource> Distinct<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
		{
			HashSet<TKey> seenKeys = new HashSet<TKey>();
			foreach (TSource element in source)
			{
				if (seenKeys.Add(keySelector(element)))
				{
					yield return element;
				}
			}
		}
	}
}